#include "stdafx.h"
#include "EventManager.h"

#include "EventHandler.h"
#include "Event.h"
#include "EventType.h"

#ifdef WIN32
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif //_DEBUG
#endif //WIND32

namespace serika
{
	namespace ut
	{
		EventManager::EventManager()
			: mFrontList(0)
			, mBackList(0)
		{
			mFrontList = &mEventList1;
			mBackList = &mEventList2;

			this->RegistryPresetEventType();
		}

		EventManager::~EventManager()
		{
			this->ClearEventList(mEventList1);
			this->ClearEventList(mEventList2);
		}

		inline void EventManager::RegistryPresetEventType()
		{
			this->RegistryEventType(EventType::Logic);
			this->RegistryEventType(EventType::UI);
			this->RegistryEventType(EventType::Network);
		}

		void EventManager::RegistryEventType(int eventType)
		{
			HandlerMap::iterator iter = mHandlerMap.find(eventType);
			if (mHandlerMap.end() == iter)
			{
				HandlerList handlerList;
				mHandlerMap.insert(std::make_pair(eventType, handlerList));
			}
		}

		void EventManager::AttachEventHandler(int eventType, EventHandler* handler)
		{
			HandlerList& handlerList = this->GetHandlerList(eventType);
			handlerList.insert(handler);
		}

		inline EventManager::HandlerList& EventManager::GetHandlerList(int eventType)
		{
			HandlerMap::iterator iter = mHandlerMap.find(eventType);
			if (mHandlerMap.end() != iter)
			{
				return iter->second;
			}

			HandlerList handlerList;
			std::pair<HandlerMap::iterator, bool> p =
				mHandlerMap.insert(std::make_pair(eventType, handlerList));
			return p.first->second;
		}

		void EventManager::DetachEventHandler(int eventType, EventHandler* handler)
		{
			HandlerList& handlerList = this->GetHandlerList(eventType);
			handlerList.erase(handler);
		}

		void EventManager::DetachEventHandler(EventHandler* handler)
		{
			for (HandlerMap::iterator iter = mHandlerMap.begin(); iter != mHandlerMap.end(); ++iter)
			{
				HandlerList& handlerList = iter->second;
				handlerList.erase(handler);
			}
		}

		void EventManager::SendEvent(Event* e)
		{
			this->DispatchEvent(e);
		}

		void EventManager::PostEvent(Event* e)
		{
			mBackList->push_back(e);
		}

		void EventManager::Dispatch()
		{
			if (mBackList->empty())
			{
				return;
			}

			this->FlipEventList();

			for (EventList::iterator iter = mFrontList->begin(); iter != mFrontList->end(); ++iter)
			{
				Event* e = *iter;
				this->DispatchEvent(e);
			}
			mFrontList->clear();
		}

		inline void EventManager::DispatchEvent(Event* e)
		{
			int type = e->GetType();

			HandlerMap::iterator iter = mHandlerMap.find(type);

			if (mHandlerMap.end() != iter)
			{
				HandlerList& handlerList = iter->second;
				for (HandlerList::iterator it = handlerList.begin(); it != handlerList.end(); ++it)
				{
					EventHandler* handler = *it;
					handler->Handle(*e);
				}
			}

			e->Release();
		}

		void EventManager::ClearEventList(EventList& eventList)
		{
			for (EventList::iterator iter = eventList.begin();
				iter != eventList.end(); ++iter)
			{
				Event* e = *iter;
				e->Release();
			}
		}

		void EventManager::FlipEventList()
		{
			EventList* tmp = mFrontList;
			mFrontList = mBackList;
			mBackList = tmp;
		}
	}
}
